<template>
  <Header msg="头部分" @refreshParent="refreshParent" class="fixed-header"></Header>
  <div ref="targetDiv" class="ycnz">
    <div class="zjneiron min_height">
      <!-- 语音播放器 -->
      <audio ref="stAudioPlayer" :src="audioUrl" controls class="hidden-audio"></audio>
      <audio ref="zjAudioPlayer" :src="audioUrl" controls class="hidden-audio"></audio>
      <el-main class="main">
        <div class="middle-1">
          <el-row :gutter="10" style="height: 50px;">
            <el-col :span="2">
              <el-button type="primary" :icon="Headset" class="responsive-font responsive-button  purple-gradient"
                @click="Generatedubbing">生成配音</el-button>
            </el-col>
            <el-col :span="2">
              <el-button type="primary" :icon="Download" class="responsive-font responsive-button  purple-gradient"
                @click="Downloaddubbing">下载配音 </el-button>
            </el-col>

            <el-col :span="2">
              <el-button type="primary" :icon="Document" class="responsive-font responsive-button purple-gradient"
                @click="Generatesubtitles">下载字幕 </el-button>
            </el-col>
            <el-col :span="2" style="visibility: hidden;">
              <el-button type="primary" :icon="Document" class="responsive-font responsive-button purple-gradient"
                @click="Downloadsubtitles">下载字幕 </el-button>
            </el-col>
            <el-col :span="8"></el-col>
            <el-col :span="2">
              <el-switch v-model="isDarkMode" style="display: none;" class="mt-2" :active-icon="Moon"
                :inactive-icon="Sunny" size="large" @change="toggleTheme" />
            </el-col>
            <el-col :span="2" style="visibility: hidden;">
              <el-button type="primary" :icon="VideoCameraFilled"
                class="responsive-font responsive-button purple-gradient" @click="Downloadvideo">下载视频
              </el-button>
            </el-col>
            <el-col :span="3"></el-col>
          </el-row>
        </div>
        <div class="middle-2 ">
          <el-row :gutter="24" class="container">
            <div class="item">
              <el-tooltip content="文案提取" placement="top">
                <a href="#" @click.prevent="importCopy" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/Importcopy.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">导入文案</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="单词近义词替换" placement="top">
                <a href="#" @click.prevent="synonym" class="clickable-col" ref="synonymRef">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/jinyici.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">近义词</div>
                </a>
              </el-tooltip>

            </div>
            <div class="item">
              <el-tooltip content="选择文本,进行多词替换" placement="top">
                <a href="#" @click.prevent="fullSynonym" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/qwjinyici.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">全文近义词</div>
                </a>
              </el-tooltip>


            </div>
            <div class="item">
              <el-tooltip content="敏感词检测" placement="top">
                <a href="#" @click.prevent="sensitiveWords" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/mingancijc.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">敏感词检测</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="单字多音纠读" placement="top">
                <a href="#" @click.prevent="multitone" class="clickable-col" ref="multitoneRef">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/jiuduoyinzi.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">多音纠读</div>
                </a>
              </el-tooltip>

            </div>
            <div class="item">
              <el-tooltip content="选择文本，进行多音字调节" placement="top">
                <a href="#" @click.prevent="batchCorrection" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/piliangjiudu.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">批量纠读</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="数字读音" placement="top">
                <a href="#" @click.prevent="numberPronunciation" class="clickable-col" ref="numberPronunciationRef">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/shuzi.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">数字读音</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="在光标位置插入儿化音" placement="top">
                <a href="#" @click.prevent="rhoticAccent" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/erhuayin.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">儿化音</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="选择文本，进行拖音操作" placement="top">
                <a href="#" @click.prevent="wordDrag" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/ciyutuoyin.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">词语拖音</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="选择文本，进行调速" placement="top">
                <a href="#" ref="localSpeedChangeRef" @click.prevent="localSpeedChange" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/jububiansu.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top8">局部变速</div>
                </a>
              </el-tooltip>
              <el-popover :virtual-ref="localSpeedChangeRef" placement="bottom" title="" width="55%" trigger="manual"
                v-model:visible="showPopover">
                <div class="button-group">
                  <el-button v-for="rate in speedChangeRates" :key="rate" size="small"
                    @click="handleLocalSpeedChangeClick(rate)">
                    {{ rate }}x
                  </el-button>
                </div>
              </el-popover>
            </div>
            <div class="item">
              <el-tooltip content="选择文本，进行顿挫调节" placement="top">
                <a href="#" ref="abortiveRegulationRef" @click.prevent="abortiveRegulation" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/duncuotiaojie.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">顿挫调节</div>
                </a>
              </el-tooltip>
              <el-popover :virtual-ref="abortiveRegulationRef" placement="bottom" title="顿挫调节" width="auto"
                trigger="manual" v-model:visible="showAbortiveRegulationPopover">
                <div class="popover-content">
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj01.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">默认</span>
                    </div>
                  </el-button>
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('ww')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj02.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">弱-弱</span>
                    </div>
                  </el-button>
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('ws')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj03.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">弱-强</span>
                    </div>
                  </el-button>
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('sws')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj04.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">强弱强</span>
                    </div>
                  </el-button>
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('sw')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj04.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">强-弱</span>
                    </div>
                  </el-button>
                  <el-button style="height: 70px;width: 50px;" @click="handleAbortiveRegulationClick('wsw')">
                    <div style="display:flex; flex-direction: column; justify-content: center;align-items: center;">
                      <img src="../images/production/dctj04.png" width="30px" height="30px">
                      <span style="margin-top: 8px;">弱强弱</span>
                    </div>
                  </el-button>
                </div>
              </el-popover>
            </div>
            <div class="item">
              <el-tooltip content="插入不同的停顿效果" placement="top">
                <a href="#" @click.prevent="insertPause" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/charutingdun.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">插入停顿</div>
                </a>
              </el-tooltip>
              <!-- 插入停顿组件 -->
              <InsertPause ref="insertPauseRef" @Completed="handleInsertPause" />
            </div>
            <div class="item">
              <el-tooltip content="暂不支持" placement="top">
                <a href="#" @click.prevent="continuousPronunciation" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/duyinlianxu.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">读音连续</div>
                </a>
              </el-tooltip>
            </div>
            <div class="item">
              <el-tooltip content="每一段末添加停顿" placement="top">
                <a href="#" @click.prevent="endStop" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/duanmo.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">段末加停顿</div>
                </a>
              </el-tooltip>
              <!-- 段末加停顿组件 -->
              <DuanMoJiaTingDun ref="duanMoJiaTingDunRef" @DuanMoJiaTingDunCompleted="handleDuanMoJiaTingDun" />
            </div>
            <div class="item">
              <el-tooltip content="点击设置全文阅读节奏" placement="top">
                <a href="#" ref="compactModeRef" @click.prevent="compactMode" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/jincoumoshi.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">紧凑模式</div>
                </a>
              </el-tooltip>
              <el-popover :virtual-ref="compactModeRef" placement="bottom" width="auto" trigger="manual"
                v-model:visible="showCompactModePopover">
                <div class="compactmode-popover-content">
                  <div class="compactmode-header">
                    <span class="compactmode-title">紧凑模式</span>
                    <el-switch class="switch" v-model="isCompactMode" @change="toggleCompactModeContent" />
                  </div>
                  <div style="width: 100%;">
                    <div class="compactmode-row">
                      当开启紧凑模式并设置时长，系统将移除超过该设置时长的静音，仅保留该设置时长的音频。
                    </div>
                    <div v-if="isCompactMode" class="compactmode-row">
                      <el-input-number style="margin-right: auto;" v-model="compactModeDuration" :min="50" :max="250"
                        :step="10" :controls="true" :step-strictly="true" />
                      <el-button style="margin-left: auto;margin-right: 8px;" type="text"
                        @click="handleCompactModeCancel">取消</el-button>
                      <el-button style="margin-left: 8px;" type="primary"
                        @click="handleCompactModeConfirm">确定</el-button>
                    </div>
                  </div>
                </div>
              </el-popover>
            </div>
            <div class="item">
              <el-tooltip content="解说增强模式" placement="top">
                <a href="#" ref="interpretationEnhancementRef" @click.prevent="interpretationEnhancement"
                  class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/jieshuo.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">解说增强</div>
                </a>
              </el-tooltip>

              <el-popover :virtual-ref="interpretationEnhancementRef" placement="bottom" width="auto" trigger="manual"
                v-model:visible="showInterpretationEnhancementPopover">
                <div class="InterpretationEnhancement-popover-content">
                  <div class="InterpretationEnhancement-header">
                    <span class="InterpretationEnhancement-title">解说增强</span>
                    <el-switch class="InterpretationEnhancement-switch" v-model="isInterpretationEnhancementEnabled"
                      @change="InterpretationEnhancementToggleContent" />
                  </div>
                  <div class="InterpretationEnhancement-content">
                    <div class="InterpretationEnhancement-row" v-if="isInterpretationEnhancementEnabled">
                      <div class="InterpretationEnhancement-text">不开启，则使用系统默认方式生成</div>
                    </div>
                    <div class="InterpretationEnhancement-row" v-if="!isInterpretationEnhancementEnabled">
                      <div class="InterpretationEnhancement-text">开启解说增强模式，声音效果更加饱满，可根据解说主题进行开启。</div>
                    </div>
                  </div>
                </div>
              </el-popover>

            </div>
            <div class="item">
              <el-tooltip content="背景音乐" placement="top">
                <a href="#" @click.prevent="backgroundMusic" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/beijinyinyue.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">背景音乐</div>
                </a>
              </el-tooltip>
              <!-- 背景音乐对话框 -->
              <BackgroundMusic ref="backgroundMusicRef" />
            </div>
            <div class="item">
              <el-tooltip content="变音" placement="top">
                <a href="#" ref="inflectionRef" @click.prevent="inflection" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/bianyin.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">{{ inflectionTitle }}</div>
                </a>
              </el-tooltip>
              <!-- 变声弹出组件 -->
              <el-popover :virtual-ref="inflectionRef" placement="bottom" title="变声" width="auto" trigger="manual"
                v-model:visible="showInflectionPopover">
                <Inflection @inflectionClick="handleInflectionClick" />
              </el-popover>
            </div>
            <div class="item">
              <el-tooltip content="配置字幕生成规则" placement="top">
                <a href="#" @click.prevent="captioning" class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/zimupeizhi.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">字幕配置</div>
                </a>
              </el-tooltip>
              <!-- 字幕配置乐对话框 -->
              <SubtitleSettings ref="subtitleSettingsRef" />

            </div>
            <div class="item">
              <el-tooltip content="多人对话" placement="top"><a href="#" @click.prevent="multiConversation"
                  class="clickable-col">
                  <div style="text-align: center;">
                    <img src="../images/buttonpicture/duorenduihua.png" width="60%" height="60%">
                  </div>
                  <div class="font_size05 margin_top6">多人对话</div>
                </a>
              </el-tooltip>
            </div>
          </el-row>
        </div>
        <div class="middle-3">
          <el-row :gutter="20" class="middle-3-1">
            <el-col :span="11">
              <div class="grid-content midele-3-bg">
                <el-row :gutter="20"
                  style="height: 60px; padding: 10px; border-bottom: 1px solid #807f7f; width: 100%; margin-left: 0px;">
                  <el-col :span="4">
                    <el-button type="primary" class="responsive-font responsive-button   purple-gradient"
                      @click="Inationenhancement"> 解说增强 </el-button>
                  </el-col>
                  <el-col :span="6"></el-col>
                  <el-col :span="5">

                  </el-col>
                  <el-col :span="4">
                    <el-button type="primary" :icon="VideoPlay" v-loading.fullscreen.lock="fullscreenLoading"
                      class="responsive-font responsive-button   purple-gradient" @click="audition">试听</el-button>
                  </el-col>
                  <el-col :span="5">
                    <el-button type="primary" :icon="VideoPlay" v-loading.fullscreen.lock="fullscreenLoading"
                      class="responsive-font responsive-button   purple-gradient"
                      @click="wholeSentence">整句试听</el-button>
                  </el-col>
                </el-row>
                <div style="height: 400px; " class="">
                  <div class="custom-textarea-container">
                    <textarea ref="textareaRef" v-model="textarea" class="custom-textarea dark_bgcolor" :style="{}"
                      maxlength="8000" placeholder="直接输入要转换的文本最多8000字" @input="getSentenceAtCursor"
                      @click="getSentenceAtCursor" @mouseup="handleMouseUp" @change="onTextareaChange"></textarea>
                    <div class="word-limit dark_word">
                      <el-row :gutter="20">
                        <el-col :span="3">
                          <el-tooltip content="段末加句号" placement="top">
                            <el-button type="info" style="height:40px; width: 40px;" :icon="Operation" circle
                              @click="segmentAddition" />
                          </el-tooltip>
                        </el-col>
                        <el-col :span="3">
                          <el-tooltip content="一键格式化" placement="top">
                            <el-button type="warning" style="height:40px; width: 40px;" :icon="Suitcase" circle
                              @click="formatting" />
                          </el-tooltip>
                        </el-col>
                        <el-col :span="3">
                          <el-tooltip content="纯文本模式" placement="top">
                            <el-button type="success" style="height:40px; width: 40px;" :icon="EditPen" circle
                              @click="plaintext" />
                          </el-tooltip>
                        </el-col>
                        <el-col :span="1"> </el-col>
                        <el-col :span="5">
                          <div style="margin-top: 12px; "> {{ textarea.length }} / 8000</div>
                        </el-col>
                        <el-col :span="3">
                          <el-tooltip content="清空文本" placement="top">
                            <el-button type="danger" style="height:40px; width: 40px;" :icon="Delete" circle
                              @click="clear" />
                          </el-tooltip>
                        </el-col>
                      </el-row>
                    </div>
                  </div>

                </div>
              </div>
            </el-col>

            <el-col :span="13">
              <div class="grid-content midele-3-bg">
                <!-- 配音角色表 -->
                <PronunciationTable ref="pronunciationRef" :voiceActorId="voiceActorId"
                  @voiceActorSelected="handleVoiceActorSelected">
                </PronunciationTable>
              </div>
            </el-col>
          </el-row>
        </div>

        <!-- 配音制作成功后语音播放器 -->
         <div v-show="listeningAudioPlayerShow" class="middle-4">
          <audio ref="listeningAudioPlayer" :src="audioUrlall" controls style="width: 100%;"></audio>
        </div>
      </el-main>
    </div>
  </div>


  <!-- 多音字纠读组件-->
  <el-popover :virtual-ref="synonymRef" v-model:visible="synonymDialogVisible" title="近义词" width="20%" trigger="manual">
    <div class="button-container">
      <el-button v-for="option in synonymOptions" :key="option" @click="handleSynonymSelect(option)">
        {{ option }}
      </el-button>
    </div>
  </el-popover>

  <el-dialog v-model="dialogfullSynonym" title="全文近义词" width="40%" :before-close="handleClose">
    <fullSynonymPage v-if="dialogfullSynonym" :msg="textarea" @textUpdated="fullSynonymUpdated" />
  </el-dialog>


  <el-dialog v-model="dialogsensitiveWords" title="敏感词检测" width="40%" :before-close="handleClose">
    <sensitiveWordsPage v-if="dialogsensitiveWords" @textUpdated="sensitiveWordsUpdated" :msg="textarea" />
  </el-dialog>
  <!-- 多音字纠读组件-->
  <el-popover :virtual-ref="multitoneRef" v-model:visible="multitoneDialogVisible" title="多音字纠读" width="20%"
    trigger="manual">
    <div class="button-container">
      <el-button v-for="option in multitoneOptions" :key="option" @click="handleMultitoneSelect(option)">
        {{ option }}
      </el-button>
    </div>
  </el-popover>

  <el-dialog v-model="dialogbatchCorrection" title="批量纠读" width="40%" :before-close="handleClose">
    <batchCorrectionPage v-if="dialogbatchCorrection" @textUpdated="batchCorrectionUpdated" :msg="textarea" />
  </el-dialog>
  <!-- 数字读音纠读组件-->
  <el-popover :virtual-ref="numberPronunciationRef" v-model:visible="numberPronunciationDialogVisible" title="数字读音"
    width="40%" trigger="manual">
    <div class="button-container">
      <el-button v-for="option in numberPronunciationOptions" :key="option"
        @click="handleNumberPronunciationSelect(option)">
        {{ option }}
      </el-button>
    </div>
  </el-popover>


  <Footer msg="脚部分"></Footer>
  <Up_module msg="回到顶部"></Up_module>
</template>



<script lang="ts">
import { ref, computed, onMounted, Ref, defineProps } from 'vue';
import {
  Moon, Sunny, Headset, Download, VideoCameraFilled, Document, Upload, VideoPlay,
  Check, Delete, Edit, Message, Search, Star, Operation, Suitcase, EditPen

} from '@element-plus/icons-vue';
//消息
import { ElMessage, ElPopover, ElMessageBox } from 'element-plus'
//页脚
import Footer from '../components/footer.vue';
//头部
import Header from '../components/header.vue';
//全同义词页面
import fullSynonymPage from "../Dubbingproduction/fullSynonymPage.vue"
//敏感词页面
import sensitiveWordsPage from "../Dubbingproduction/sensitiveWordsPage.vue"
//批量纠错页面
import batchCorrectionPage from "../Dubbingproduction/batchCorrectionPage.vue"
//回到顶部
import Up_module from '../components/up_module.vue';
//配音角色表
import PronunciationTable from '../components/components/PronunciationTable.vue';
//首页样式
import "../components/css/Homepage.css";
//axios
import axios from 'axios';
//element-plus
import { el } from 'element-plus/es/locale';
//插入暂停
import InsertPause from './InsertPause.vue';
//段末加停顿
import DuanMoJiaTingDun from './DuanMoJiaTingDun.vue';
//背景音乐
import BackgroundMusic from './BackgroundMusic.vue';
//背景音乐内容
import BackgroundMusicContent from './BackgroundMusicContent.vue';
//变声
import Inflection from './Inflection.vue';

///切割字幕
import { useAudio, TextSegment, getAudioDuration, formatDuration, textToSpeech, textToSpeechBlob, mergedAudio } from '../components/js/Dubbingproduction/Audiomerging';
///字幕生成
import { Dsubtitles } from '../components/js/Dubbingproduction/subtitles';

// 字幕配置
import SubtitleSettings from './SubtitleSettings.vue';
//类型  
import { RestaurantItem, IVoiceActor, VoiceActor, IVoiceTag, IVoiceCat, IVoiceStyle, Speech, VoiceStyle, VoiceRoleArgs, ISpeech, GetBaseURL, AudioRecord } from '../../composables/types';
//路由
import { stringifyQuery } from 'vue-router';
import { tryOnUnmounted } from '@vueuse/core';

///配置制作页面

// 定义一个接口来描述每个段落的结构 用来接收字幕生成的数据
interface SegmentInfo {
  index: number;
  text: string;
  duration: number;
  audioUrl: string;

}

// 定义接口描述音频返回
export interface Audioreturn {
  duration: number;
  audioUrl: string;
  code: number;
  message: string;

}

///导出
export default {
  components: {
    //页脚
    Footer,
    //头部
    Header,
    //配音角色表
    PronunciationTable,
    //回到顶部
    Up_module,
    //全同义词页面
    fullSynonymPage,
    //敏感词页面
    sensitiveWordsPage,
    //批量纠错页面
    batchCorrectionPage,
    //插入暂停
    InsertPause,
    //段末加停顿
    DuanMoJiaTingDun,
    //背景音乐
    BackgroundMusic,
    //背景音乐内容
    BackgroundMusicContent,
    //变声
    Inflection,
    //字幕设置
    SubtitleSettings
  },
  methods: {

  },
  // 传入的参数
  props: {
    //声音广场传入的配音角色Id
    voiceActorId: {
      type: Number,
      default: 0
    },
    //会员中心的配音记录传入配音记录Id
    audioId:{
      type: Number,
      default: 0
    } 
  },

  setup(props) {
    // 接口地址
    const baseUrl: string = GetBaseURL();
    // 配音角色表组件引用
    const pronunciationRef = ref(null);
    //是否暗黑模式
    const isDarkMode = ref(false);
    //目标div
    const targetDiv = ref(null);
    //文本框
    const textarea = ref('');
    //全同义词对话框
    const dialogfullSynonym = ref(false)
    // 生成的音频地址
    const dialogsensitiveWords = ref(false)
    ///批量纠读
    const dialogbatchCorrection = ref(false)

    const audioUrl = ref('');
    // 试听音频播放器
    const listeningAudioPlayer = ref<HTMLAudioElement | null>(null);
    //试听音频播放器
    const stAudioPlayer = ref<HTMLAudioElement | null>(null);
    //字幕音频播放器
    const zjAudioPlayer = ref<HTMLAudioElement | null>(null);
    // 文本框引用
    const textareaRef = ref<HTMLTextAreaElement | null>(null);
    // 整句试听文本
    const sentenceText = ref('');

    const fullSynonymPageTextContent = ref('');
    //选中的文本
    const selectedText = ref('');
    //多音字对话框
    const multitoneDialogVisible = ref(false);
    //数字发音对话框
    const numberPronunciationDialogVisible = ref(false);
    //多音字选项
    const multitoneOptions = ref(['le5', 'liao3', 'liao4']);
    //同义词选项
    const synonymOptions = ref(['好', '真的', '还好']);
    //同义词对话框
    const synonymDialogVisible = ref(false);
    //数字发音选项
    const numberPronunciationOptions = ref(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']);
    //选中的文本起始位置
    const selectedTextStart = ref(0);
    //选中的文本结束位置
    const selectedTextEnd = ref(0);
    // 试听音频播放器 或 整句试听音频播放器
    const audioPlayer = ref<HTMLAudioElement | null>(null);
    // 定义音频状态和音频是否改变
    // -1:初始化状态，0:试听，1:整句试听，2:生成配音,
    const audioState = ref({ audioType: 0, audioChanged: false });
    // 插入停顿组件
    const insertPauseRef = ref(null);
    //光标在文本中的当前位置
    const cursorPosition = ref(0);
    // 段末加停顿组件
    const duanMoJiaTingDunRef = ref(null);
    // 当前光标所在的段落
    const currentParagraph = ref('');
    // 局部变速组件引用
    const localSpeedChangeRef = ref(null);
    // 显示局部变速
    const showPopover = ref(false);
    // 局部变速
    const speedChangeRates = ref([0.5, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.4, 1.5]);
    // 顿挫调整组件引用
    const abortiveRegulationRef = ref(null);
    // 显示局部变速
    const showAbortiveRegulationPopover = ref(false);
    // 紧凑模式组件引用
    const compactModeRef = ref(null);
    // 显示紧凑模式
    const showCompactModePopover = ref(false);
    // 显示紧凑模式第2行组件audioUrl2.value
    const isCompactMode = ref(false);
    // 紧凑模式时长
    const compactModeDuration = ref(60);
    // 显示解说增强组件引用
    const showInterpretationEnhancementPopover = ref(false);
    //显示解说增强组件内容
    const isInterpretationEnhancementEnabled = ref(false);
    // 解说增强组件引用
    const interpretationEnhancementRef = ref(null);
    // 背景音乐组件引用
    const backgroundMusicRef = ref(null);
    // 变声组件引用
    const inflectionRef = ref(null);
    // 变声弹窗显示状态
    const showInflectionPopover = ref(false);
    // 变声组件标题
    const inflectionTitle = ref("变声");
    // 多音字纠读 组件引用
    const multitoneRef = ref(null);
    //同义词纠读 组件引用
    const synonymRef = ref(null);
    //数字发音纠读 组件引用
    const numberPronunciationRef = ref(null);
    // 字幕设置组件引用
    const subtitleSettingsRef = ref(null);
    // 解构出 下载合成音频地址
    const { Subtitlesegmentation } = useAudio();
    ///字幕生成
    const { Titlegeneration, Captioncomposition } = Dsubtitles();
    ///字幕段落公共量
    const segments: Ref<TextSegment[]> = ref([]);
    //全屏显示加载中
    const fullscreenLoading = ref(false);

    const audioUrlipdz = ref('https://frp.qianbianwanhua.vip/10月22日.WAV');
    //音频时长
    const duration = ref<number | null>(null);
    //音频时长格式化
    const formattedDuration = ref('');
    //错误信息
    const error = ref('');
    //段落列表
    const segmentsList: Ref<SegmentInfo[]> = ref([]);
    //音频地址
    const audioUrlall = ref('');
    //配音角色id，从声音广场传入
    const voiceActorId=ref(props.voiceActorId);
    //listeningAudioPlayer显示或隐藏
    const listeningAudioPlayerShow=ref(false);


    /**
     * 当文本发生变化时的处理函数
     * 此函数旨在处理文本变化事件，具体操作是清空音频URL
     * @param {Event} event - 触发的事件对象，这里未直接使用，但可能在将来用于扩展功能
     */
    const onTextChange = (event: Event) => {
      // 清空音频URL
      resetAudio();
    };

    //调用ts


    /**
     * 生成配音，试听，整句试听的合法性验证
     * 验证用户不是会员或者是否足够的余额
     * 在当前上下文中，验证逻辑尚未实现，因此默认返回 true
     * 
     * @returns {boolean} 验证结果，true 表示验证通过
     */
    function validate(): boolean {
      //验证结果
      let result: boolean = true;
      return result;
    }

    /**
     * 将文本转换为音频并播放
     * @param text 要转换为音频的文本内容
     * 该函数通过引用调用一个方法，将给定的文本转换为音频并播放出来
     * 为什么需要这个函数：为了在界面上提供文本转语音的功能，增强用户体验
     * 为什么是这样实现：直接调用之前定义好的方法，简化代码逻辑，提高可读性
     */
    async function callTextToAudioPlay(text: string): Promise<string> {
      //生成配音参数
      let speechArgs: Speech = new Speech();
      //当前配音角色和配音参数
      let currentItem: VoiceActor = new VoiceActor(0, '', '', '')

      if (!pronunciationRef.value) {
        console.log(pronunciationRef.value);
        throw new Error('pronunciationRef 未定义');
      }

      try {
        if (pronunciationRef.value) {
          currentItem = pronunciationRef.value.currentItem;
          // 设置参数
          speechArgs.text = text;
          speechArgs.voiceName = currentItem.ShortName;
          speechArgs.rate = currentItem.paceValue.toString(); // 语速
          speechArgs.volume = '+10.00%'; // 音量
          speechArgs.pitch = (currentItem.pitchValue * 100).toString() + "%"; // 音调
          speechArgs.style = currentItem.VoiceStyle.en_name; // 讲话风格
          speechArgs.role = ''; // 讲话角色扮演
          speechArgs.styleDegree = currentItem.styleDegree.toString(); // 讲话风格的强度
          speechArgs.breakTime = '250'; // 停顿时间
        }

        //显示全屏遮罩
        fullscreenLoading.value = true;
        // 调用将文本转换为音频并播放的函数
        const result = await textToSpeechBlob(speechArgs);
        //关闭全屏遮罩
        fullscreenLoading.value = false;
        audioUrl.value = result;
        console.log('文本转语音成功：', result);
        return result;
      } catch (error) {
        fullscreenLoading.value = false;
        console.error('文本转语音失败：', error);
        throw error;
      }
    }

    ///选中的字
    const handleMouseUp = () => {
      const selection = window.getSelection();
      selectedText.value = selection ? selection.toString() : '';
    };

    /**
 * 试听，将文本转换为音频并播放
 * 此函数读取textarea的值，并将其作为参数传递给audioPlay函数进行播放
 */
    function shiTing() {
      try {
        // 从textarea元素获取用户输入的文本
        let text: string = textarea.value;
        audioPlayer.value = stAudioPlayer.value;

        if (audioState.value.audioType == 0) {
          if (!audioPlayer.value.paused) {
            //正在播放，则停止播放，并清空音频URL
            //清空音频URL
            resetAudio();
            return;
          }
        }

        if (cursorPosition.value >= 0) {
          text = text.substring(cursorPosition.value);
          //清空音频URL
          resetAudio();
          //清空textarea中的光标位置,试听起始位置
          cursorPosition.value = -1;
          if (audioPlayer.value) {
            // 设置当前状态为试听
            audioState.value.audioType = 0;
            if (text) {
              // 调用audioPlay函数，将获取的文本作为参数传递，以生成并播放相应的音频
              audioPlay(text);
              // 清空整句试听文本
              sentenceText.value = "";
              // 处理按钮点击事件，使 textarea 失去焦点
              if (textareaRef.value) {
                textareaRef.value.blur();
              }
            }
            else {
              errorMessge("没有文本");
            }
          }
        }
        else {
          errorMessge("请指定要开始试听的位置");
          return;
        }


      }
      catch (error) {
        console.error('试听失败', error.message);
      }
    }

    ///关闭对话框
    const handleClose = () => {
      dialogfullSynonym.value = false;
      dialogsensitiveWords.value = false;
      dialogbatchCorrection.value = false;

    };

    /**
     * 整句试听，将文本转换为音频并播放
     * 此函数读取textarea的值，并将其作为参数传递给audioPlay函数进行播放
     */
    function zhengJuShiTing() {
      try {
        // 从textarea元素获取用户输入的文本
        let text: string = sentenceText.value;
        audioPlayer.value = zjAudioPlayer.value;

        //清空音频URL
        resetAudio();

        // 设置当前状态为试听
        audioState.value.audioType = 1;

        //清空textarea中的光标位置,试听起始位置
        cursorPosition.value = -1;

        if (text) {
          // 检查是否有正在播放的音频
          if (audioPlayer.value) {
            // 调用将文本转换为音频并播放的函数
            callTextToAudioPlay(text).then(result => {
              // 加载并播放生成的音频
              loadPlayAudio();
            }).catch(
              error => {
                console.error('文本转语音出错:', error);
                handleAudioError(error);
              }
            );
          }

          // 清空整句试听文本
          sentenceText.value = "";
          // 处理按钮点击事件，使 textarea 失去焦点
          if (textareaRef.value) {
            textareaRef.value.blur();
          }

        }
        else {
          errorMessge("请选择有效的试听位置");
        }
      }
      catch (error) {
        console.error('整句试听失败', error.message);
      }
    }

    /**
         * 获取光标所在行的句子
         * 此方法在textarea输入事件触发时调用，获取光标位置并提取所在行的句子
         */
    function getSentenceAtCursor() {
      let value: string = "";

      if (textareaRef.value) {
        value = textareaRef.value.value;
        cursorPosition.value = textareaRef.value.selectionStart || 0;
      }

      // 获取光标所在行的起始和结束位置
      const lines = value.split('\n');
      let currentLineIndex = 0;
      let currentLineStart = 0;
      for (let i = 0; i < lines.length; i++) {
        const lineLength = lines[i].length + 1; // 加1是因为换行符
        if (currentLineStart + lineLength > cursorPosition.value) {
          currentLineIndex = i;
          break;
        }
        currentLineStart += lineLength;
      }
      //当前行  
      const currentLine = lines[currentLineIndex];
      //提取句子
      const sentence = extractSentence(currentLine, cursorPosition.value - currentLineStart);

      // 整句试听文本
      sentenceText.value = sentence;

      // console.log('当前行的句子和当前位置:', cursorPosition.value, sentence);
      return sentence;
    }

    /**
        * 从指定行中提取句子
        * @param {string} line - 当前行的文本
        * @param {number} cursorOffset - 光标在当前行中的偏移量
        * @returns {string} - 提取的句子
        */
    function extractSentence(line: string, cursorOffset: number) {
      // 从光标位置开始向后查找句号或感叹号
      const start = line.slice(0, cursorOffset).search(/[.!?]/);
      const end = line.slice(cursorOffset).search(/[.!?]/);

      if (start === -1 && end === -1) {
        return line; // 没有找到句号或感叹号，返回整行
      }
      //起始索引
      const startIndex = start === -1 ? 0 : start + 1;
      //结束索引
      const endIndex = end === -1 ? line.length : cursorOffset + end + 1;

      return line.slice(startIndex, endIndex);
    }



    // 处理音频错误
    const handleAudioError = (error: Error) => {
      if (error.name === 'NotAllowedError') {
        console.error('用户拒绝了音频播放权限');
      } else if (error.name === 'NotReadableError') {
        console.error('音频文件无法读取');
      } else if (error.name === 'NetworkError') {
        console.error('网络错误导致无法加载音频文件');
      } else if (error.name === 'AbortError') {
        console.error('音频播放被取消');
      } else {
        console.error('未知错误：', error);
      }
    };

    // 使用正则表达式按中文标点符号分组
    function splitByChinesePunctuation(text: string): string[] {
      // 匹配中文标点符号
      const chinesePunctuationRegex = /[\u3000-\u303F\uFF00-\uFFEF]/g;
      // 按中文标点符号分组
      return text.split(chinesePunctuationRegex).filter(Boolean);
    };

    /**
    * 处理配音演员选择事件
    * 当选择配音演员时，调用此函数来执行相关操作
    * @param {VoiceActor} data - 传递给函数的数据，此处未使用，但可能在函数未来扩展中用于处理选择信息
    */
    function handleVoiceActorSelected(data: VoiceActor) {
      let voiceData: VoiceActor = undefined;

      //清空音频URL
      //resetAudio();

      //清空textarea中的光标位置,试听起始位置
      cursorPosition.value = -1;
      //整句试听文本清空
      sentenceText.value = ""
      // 重置音频状态为初始状态
      audioState.value.audioType = -1;

      //配音文本不为空则保存到服务器中
      if (!(textarea.value == "" || textarea.value == null || textarea.value == undefined)) {
        if (pronunciationRef.value != null && pronunciationRef.value.currentItem != null && pronunciationRef.value.currentItem != undefined) {
          voiceData = pronunciationRef.value.currentItem;
          saveTempData(voiceData, textarea.value);
        }
      }
    }


    /**
     * 重置音频
     * 
     * 此函数用于将音频URL重置为空字符串
     * 主要用于在应用中清除当前的音频源，以便用户可以上传或选择新的音频文件
     */
    function resetAudio() {
      // 清空音频URL,不清空
      audioUrl.value = "";
    }

    //按标点符号分割文本后一句一句的生成配音并播放
    function sentenceAudioPlay(text: string): void {
      try {
        // 检查是否有正在播放的音频
        if (audioPlayer.value) {
          if (audioUrl.value) {
            // 如果有音频在播放，根据音频播放状态决定是暂停还是继续播放
            if (audioPlayer.value.paused) {
              // 如果音频暂停，则继续播放
              playAudio();
            } else {
              // 如果音频正在播放，则暂停播放
              pauseAudio();
            }

            // 返回，以避免执行后续代码
            return;
          }
        }

        // 调用将文本转换为音频并播放的函数
        callTextToAudioPlay(text).then(result => {
          // 加载并播放生成的音频
          loadPlayAudio();
        }).catch(
          error => {
            console.error('文本转语音出错:', error);
            handleAudioError(error);
          }
        );
      }
      catch (error) {
        console.error('播放音频失败', error.message);
      }
    }

    /**
     * 播放音频函数
     * 
     * 该函数首先检查是否存在正在播放的音频，如果存在，则根据当前音频的播放状态决定是暂停还是继续播放
     * 如果不存在正在播放的音频，则通过调用`callTextToAudioPlay`和`loadPlayAudio`函数来生成并播放音频
     * 
     * @param text {string} - 需要转换为音频并播放的文本
     */
    function audioPlay(text: string): void {
      try {
        // 检查是否有正在播放的音频
        // if (audioPlayer.value) {
        //   // 调用将文本转换为音频并播放的函数
        //   callTextToAudioPlay(text).then(result => {
        //     // 加载并播放生成的音频
        //     loadPlayAudio();
        //   }).catch(
        //     error => {
        //       console.error('文本转语音出错:', error);
        //       handleAudioError(error);
        //     }
        //   );
        // }

        // 检查是否有正在播放的音频
        if (audioPlayer.value) {
          if (!audioUrl.value) {

            // 调用将文本转换为音频并播放的函数
            callTextToAudioPlay(text).then(result => {
              // 加载并播放生成的音频
              loadPlayAudio();
            }).catch(
              error => {
                console.error('文本转语音出错:', error);
                handleAudioError(error);
              }
            );
          }
          else {

            // 如果有音频在播放，根据音频播放状态决定是暂停还是继续播放
            if (audioPlayer.value.paused) {
              // 如果音频暂停，则继续播放
              playAudio();
            } else {
              // 如果音频正在播放，则暂停播放
              pauseAudio();
            }

            // 返回，以避免执行后续代码
            return;
          }
        }


      }
      catch (error) {
        console.error('播放音频失败', error.message);
      }
    }


    // 加载并播放音频
    const loadPlayAudio = () => {
      if (audioPlayer.value) {
        // 尝试加载音频
        audioPlayer.value.load();

        // 定义 canplay 事件处理函数
        const handleCanPlay = () => {
          // 移除 canplay 事件监听器
          audioPlayer.value.removeEventListener('canplay', handleCanPlay);

          // 播放音频
          audioPlayer.value.play().catch(error => {
            console.error('语音播放出错:', error);
            handleAudioError(error);
          });
        };

        // 监听 canplay 事件
        audioPlayer.value.addEventListener('canplay', handleCanPlay);
      }
    };

    // 播放音频
    const playAudio = () => {
      if (audioPlayer.value) {
        audioPlayer.value.play();
      }
    };

    /**
     * 暂停音频播放
     * 当audioPlayer存在时，调用其pause方法暂停播放
     */
    const pauseAudio = () => {
      if (audioPlayer.value) {
        audioPlayer.value.pause();
      }
    };

    const toggleTheme = (value: boolean) => {

    }
    // 定义一个函数来提取文件名
    function extractFileName(url: string) {
      // 使用 URL 对象解析 URL
      const parsedUrl = new URL(url);
      // 获取路径部分并分割成数组
      const pathSegments = parsedUrl.pathname.split('/');
      // 取最后一个元素作为文件名
      return pathSegments[pathSegments.length - 1];
    }


    ///成功提示
    const successMessge = (value: string) => {
      ElMessage({
        message: value,
        type: 'success',
      })
    }
    //错误提示
    const errorMessge = (value: string) => {
      ElMessage.error(value)
    }

    /**
     * 设置cookie
     * @param name {string} - 需要设置的cookie名称
     * @param value {string} - 需要设置的cookie值
     * @param days {number} - 需要设置的cookie有效期，单位为天
     */
    function setCookie(name: string, value: string, days: number) {
      const d = new Date();
      d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
      const expires = "expires=" + d.toUTCString();
      document.cookie = name + "=" + value + ";" + expires + ";path=/";
    };

    /**
     * 获取cookie
     * @param name {string} - 需要获取的cookie名称
     * @returns {string | null} - 返回获取到的cookie值，如果未找到则返回null
     */
    function getCookie(name: string) {
      const nameEQ = name + "=";
      const ca = document.cookie.split(';');
      for (let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
      }
      return null;
    };

    /**
     * 段末添加
     * 在文本末尾添加两个换行符
     */
    function segmentAddition() {

      // 检查 textarea.value 是否为空
      if (!textarea.value.trim()) {
        errorMessge("请先导入文案！再进行段末添加");
        return;
      }
      // 将文本按行分割
      let lines = textarea.value.split('\n');

      // 处理每一行
      lines = lines.map(line => {
        // 去掉行尾的空白字符
        line = line.trim();

        // 如果行不为空且最后一个字符不是标点符号，则添加句号
        if (line && !/[。！？，：；.!?,;:]$/.test(line)) {
          line += '。';
        }

        return line;
      });

      // 将处理后的行重新组合成文本
      textarea.value = lines.join('\n');

      console.log("段末添加成功" + textarea.value);
      successMessge("段末添加句号成功");
    }

    /**
       * 格式化
       * 
       * 此函数用于去除文本中的多余空格，并将连续的空格替换为单个空格
       */
    function formatting() {
      // 检查 textarea.value 是否为空
      if (!textarea.value.trim()) {
        errorMessge("请先导入文案！再进行格式化");
        return;
      }
      textarea.value = textarea.value.replace(/\s+/g, ' ').trim();
      successMessge("格式化成功")
    }

    /**
     * 纯文本
     * 
     * 此函数用于去除文本中的HTML标签，只保留纯文本内容
     */
    function plaintext() {
      // 检查 textarea.value 是否为空
      if (!textarea.value.trim()) {
        errorMessge("请先导入文案！再进行纯文本");
        return;
      }
      textarea.value = textarea.value.replace(/<[^>]*>/g, '');
      successMessge("纯文本成功")
    }
    /**
     * 清空
     * 
     * 此函数用于清空textarea中的文本内容
     */
    function clear() {
      ElMessageBox.confirm(
        '确定要清空所有内容吗？此操作不可撤销。',
        '清空文本',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }
      )
        .then(() => {
          textarea.value = '';
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: '已取消清空操作',
          })
        })
    }

    /**
     * 解说增强
     * 
     * 此函数用于显示解说增强成功的消息
     */
    function Inationenhancement() {
      successMessge("解说增强成功")

    }

    /**
       * 试听
       * 
       * 此函数用于显示试听成功的消息
       */
    function audition() {
      //successMessge("试听成功")
      shiTing();

    }

    /**
     * 整句试听
     * 
     * 此函数用于显示整句试听成功的消息
     */
    function wholeSentence() {
      //successMessge("整句试听成功")
      zhengJuShiTing();

    }

    /**
       * 功能选择
       * 
       * 此函数用于显示功能选择成功的消息
       */
    function handleClick(value: string) {
      successMessge(value)
      // 在这里定义点击后的操作

      // 例如，可以在这里打开一个模态框或者跳转到其他页面
    }


    /**
     * 生成配音
     * 
     * 此函数用于生成配音并显示生成配音成功的消息
     */
    async function Generatedubbing() {
      try {
        // 检查文本是否为空
        if (!textarea.value || !textarea.value.trim()) {
          errorMessge("请先输入或导入文本内容");
          return;
        }

        ///清空配音列表
        segmentsList.value = [];
        // 从textarea元素获取用户输入的文本
        let text: string = textarea.value;
        //生成配音参数
        let speechArgs: Speech;
        //当前配音角色和配音参数
        let currentItem: VoiceActor = new VoiceActor(0, '', '', '')
        // 清空整句试听文本
        sentenceText.value = "";

        let audioreturn: Audioreturn;
        // 设置当前状态为生成配音
        audioState.value.audioType = 2;

        segments.value = Subtitlesegmentation(text);

        ///循环生成配音
        for (let index = 0; index < segments.value.length; index++) {
          const segment = segments.value[index];

          // 调用将文本转换为音频并播放的函数
          speechArgs = new Speech();
          if (pronunciationRef.value) {
            currentItem = pronunciationRef.value.currentItem;
            // 设置参数
            speechArgs.text = segment.text;
            speechArgs.voiceName = currentItem.ShortName;
            speechArgs.rate = currentItem.paceValue.toString(); // 语速
            speechArgs.volume = '+10.00%'; // 音量
            speechArgs.pitch = (currentItem.pitchValue * 100).toString() + "%"; // 音调
            speechArgs.style = currentItem.VoiceStyle.en_name; // 讲话风格
            speechArgs.role = ''; // 讲话角色扮演
            speechArgs.styleDegree = currentItem.styleDegree.toString(); // 讲话风格的强度
            speechArgs.breakTime = '250'; // 停顿时间
          }
          console.log("segment.text", segment.text);
          //生成配音并取得音频地址
          audioreturn = await textToSpeech(speechArgs);
          if (audioreturn.code != 200) {
            errorMessge(audioreturn.message);
            return;
          }


          //播放音频
          //loadPlayAudio();

          ///获取音频时长
          //const durationInSeconds = await getAudioDuration(audioUrl.value);
          segmentsList.value.push({
            index: index,
            text: segment.text,
            duration: audioreturn.duration,
            audioUrl: audioreturn.audioUrl
          });


        }
        ///合并数据
        const restring = await mergedAudio(segmentsList.value);
        audioUrlall.value = restring;


        //显示配音制作音频播放器
        listeningAudioPlayerShow.value=true;
        audioPlayer.value = listeningAudioPlayer.value;
        successMessge("生成配音成功");


        // if (validate() == false) {
        //   // 验证没通过
        //   return;
        // }

        // 如果存在文本，则执行生成配音逻辑
        // if (text) {
        //   if (audioPlayer.value) {
        //     // 显示音频播放器
        //     audioPlayer.value.style = 'display:block';
        //   }
        //   successMessge("生成配音成功");
        //   // 调用audioPlay函数，将获取的文本作为参数传递，以生成并播放相应的音频
        //   audioPlay(text);

        //   // 清空整句试听文本
        //   sentenceText.value = "";
        //   // 处理按钮点击事件，使 textarea 失去焦点
        //   if (textareaRef.value) {
        //     textareaRef.value.blur();
        //   }
        // }
        // else {
        //   // 如果没有文本，显示错误信息
        //   errorMessge("没有文本");
        // }

      } catch (error) {
        console.error('生成配音失败', error.message);
      }
    }


    /**
     * 异步下载配音文件
     * 此函数尝试从给定的audioUrl.value下载音频文件，并触发浏览器下载
     * 如果audioUrl.value为空，则显示错误消息
     */

    async function Downloaddubbing() {
      const fullUrl = audioUrlall.value;
      if (!fullUrl) {
        errorMessge("没有可下载的音频");
        return;
      }


      const prefix = "https://api.turuio.net/";
      const urlss = fullUrl.replace(prefix, "/api/");
      alert(urlss);
      fullscreenLoading.value = true;

      try {
        // 使用 fetch 获取文件
        const response = await fetch(urlss);

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        // 获取 blob 数据
        const blob = await response.blob();

        // 创建下载链接
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;

        // 设置文件名
        const contentDisposition = response.headers.get('content-disposition');
        // 提取文件名
        let fileName = fullUrl.split('/').pop() || 'audio.mp3';
        if (contentDisposition) {
          const fileNameMatch = contentDisposition.match(/filename="?(.+)"?/i);
          if (fileNameMatch && fileNameMatch.length === 2)
            fileName = fileNameMatch[1];
        }
        link.setAttribute('download', fileName);

        // 触发下载
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);

        successMessge("音频下载成功");
      } catch (error) {
        console.error('下载音频失败：', error);
        errorMessge("下载音频失败");
      } finally {
        fullscreenLoading.value = false;
      }
    }


    /**
     * 下载视频
     * 此函数用于获取音频时长并显示完整精度的时长
     */
    async function Downloadvideo() {
      try {
        const durationInSeconds = await getAudioDuration(audioUrlipdz.value);
        duration.value = durationInSeconds; // 这里保存的是完整精度的时长
        console.log(`完整时长: ${duration.value} 秒`);
      } catch (err) {
        error.value = '获取音频时长失败';
        console.error(err);
      }
    }



    /**
     * 生成字幕
     * 
     * 此函数用于生成字幕并显示生成字幕成功的消息
     */
    function Generatesubtitles() {
      ///生成字幕
      const fullUrl = audioUrlall.value;
      if (!fullUrl) {
        errorMessge("没有可下载的字幕");
        return;
      }
      const composedCaptions = Captioncomposition(segmentsList.value, audioUrlall.value);
      successMessge(composedCaptions);

    }

    /**
     * 下载字幕
     * 
     * 此函数用于下载字幕并显示字幕内容
     */
    function Downloadsubtitles() {
      segments.value.forEach((segment, index) => {

        successMessge(`段落 ${index + 1}: ${segment.text}`);
      });
    }

    /**
     * 刷新
     * 主要针对夜间模式
     * 此函数用于刷新页面，主要针对夜间模式
     */
    function refreshParent() {

      const user = getCookie('nightMode');
      if (user == "") {
        targetDiv.value.className = "light";
      } else {

        targetDiv.value.className = user;
      }
    };

    /**
     * 近义词更新
     * 
     * 此函数用于更新近义词并显示更新后的文本
     */
    const fullSynonymUpdated = (updatedText: string) => {
      dialogfullSynonym.value = false;
      textarea.value = updatedText;
      // 在这里处理更新后的文本 
      // 例如，可以将它赋值给某个变量或者进行其他操作   
    }

    /**
       * 敏感词更新
       * 
       * 此函数用于更新敏感词并显示更新后的文本
       */
    const sensitiveWordsUpdated = (updatedText: string) => {
      dialogsensitiveWords.value = false;
      textarea.value = updatedText;
      // 在这里处理更新后的文本 
      // 例如，可以将它赋值给某个变量或者进行其他操作   
    }

    /**
     * 批量纠读更新
     * 
     * 此函数用于更新批量纠读并显示更新后的文本
     */
    const batchCorrectionUpdated = (updatedText: string) => {
      dialogbatchCorrection.value = false;
      textarea.value = updatedText;
    }


    /**
     * 导入文案
     * 
     * 此函数用于导入文案并显示多音字和数字读音选项
     */
    function importCopy() {

      multitoneOptions.value = ['le5', 'liao3', 'liao4', 'ffafaf'];
      numberPronunciationOptions.value = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
      // 创建一个临时的 file input 元素
      const fileInput = document.createElement('input')
      fileInput.type = 'file'
      fileInput.accept = '.txt'
      // 监听文件选择事件
      fileInput.onchange = (event) => {
        const file = event.target.files[0]
        if (file && file.type === 'text/plain') {
          const reader = new FileReader()
          reader.onload = (e) => {
            textarea.value = e.target.result


          }
          reader.onerror = (e) => {
            errorMessge('文件读取失败')
          }
          reader.readAsText(file)
        } else {
          errorMessge('请选择一个有效的 txt 文件')
        }
      }

      // 触发文件选择对话框
      fileInput.click()


    }

    /**
     * 近义词
     * 
     * 此函数用于获取选中文本并显示近义词对话框
     */
    function synonym() {
      const selection = window.getSelection();
      if (selection && selection.toString().trim()) {
        selectedText.value = selection.toString().trim();
        if (selectedText.value.length != 1) {
          errorMessge("请选择单字");
          return;
        } else {
          const range = selection.getRangeAt(0);
          selectedTextStart.value = range.startOffset;
          selectedTextEnd.value = range.endOffset;
          synonymDialogVisible.value = true;
        }
      } else {
        errorMessge("请先选择要纠读的文本");
      }
    }

    /**
     * 近义词选择
     * 
     * 此函数用于选择近义词并显示更新后的文本
     */
    function handleSynonymSelect(option: string) {
      const textarea = textareaRef.value;
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const beforeText = textarea.value.substring(0, start);
      const afterText = textarea.value.substring(end);
      textarea.value = beforeText + option + afterText;
      // 更新 v-model 绑定的值
      textarea.value = textarea.value;
      synonymDialogVisible.value = false;
    }


    /**
   * 全文近义词
   * 
   * 此函数用于显示全文近义词对话框
   */
    function fullSynonym() {
      dialogfullSynonym.value = true;

    }

    /**
     * 敏感词
     * 
     * 此函数用于显示敏感词对话框
     */
    function sensitiveWords() {
      dialogsensitiveWords.value = true;

    }

    /**
     * 多音字
     * 
     * 此函数用于获取选中文本并显示多音字对话框
     */
    function multitone() {
      const selection = window.getSelection();
      if (selection && selection.toString().trim()) {
        selectedText.value = selection.toString().trim();
        if (selectedText.value.length != 1) {
          errorMessge("请选择单字");
          return;
        } else {
          const range = selection.getRangeAt(0);
          selectedTextStart.value = range.startOffset;
          selectedTextEnd.value = range.endOffset;
          multitoneDialogVisible.value = true;
        }
      } else {
        errorMessge("请先选择要纠读的文本");
      }
    }

    /**
     * 多音字选择
     * 
     * 此函数用于选择多音字并显示更新后的文本
     */
    function handleMultitoneSelect(option: string) {
      const textarea = textareaRef.value;
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const beforeText = textarea.value.substring(0, start);
      const afterText = textarea.value.substring(end);
      textarea.value = beforeText + option + afterText;
      // 更新 v-model 绑定的值
      textarea.value = textarea.value;
      multitoneDialogVisible.value = false;
    }


    /**
     * 批量纠读
     * 
     * 此函数用于显示批量纠读对话框
     */
    function batchCorrection() {
      dialogbatchCorrection.value = true;

    }

    /**
     * 数字读音
     * 
     * 此函数用于获取选中文本并显示数字读音对话框
     */
    function numberPronunciation() {
      const selection = window.getSelection();
      if (selection && selection.toString().trim()) {
        selectedText.value = selection.toString().trim();
        if (!/^\d+$/.test(selectedText.value)) {
          errorMessge("请选择数字");
          return;
        } else {
          const range = selection.getRangeAt(0);
          selectedTextStart.value = range.startOffset;
          selectedTextEnd.value = range.endOffset;
          numberPronunciationDialogVisible.value = true;
        }
      } else {
        errorMessge("请先选择要纠读的文本");
      }


    }

    /**
     * 数字读音选择
     * 
     * 此函数用于选择数字读音并显示更新后的文本
     */
    function handleNumberPronunciationSelect(option: string) {
      const textarea = textareaRef.value;
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const beforeText = textarea.value.substring(0, start);
      const afterText = textarea.value.substring(end);
      textarea.value = beforeText + option + afterText;
      // 更新 v-model 绑定的值
      textarea.value = textarea.value;
      numberPronunciationDialogVisible.value = false;
    }

    /**
     * 儿化音
     * 
     * 此函数用于在选中文本末尾或光标位置插入"儿"字
     */
    function rhoticAccent() {
      const textarea = textareaRef.value;
      if (textarea) {
        const start = textarea.selectionStart;
        const end = textarea.selectionEnd;
        const text = textarea.value;
        // 在选中文本末尾或光标位置插入"儿"字
        const newText = text.slice(0, end) + "[=er]" + text.slice(end);
        // 更新 textarea 的值
        textarea.value = newText;
        // 更新 v-model 绑定的值
        textarea.value = newText;
        // 将光标位置设置到插入的"儿"字之后
        textarea.setSelectionRange(end + 1, end + 1);
        // 让 textarea 重新获得焦点
        textarea.focus();
      } else {
        errorMessge("无法获取文本区域");
      }
    }

    /**
     * 词语拖音
     * 
     * 此函数用于显示词语拖音对话框
     */
    function wordDrag() {
      //successMessge("词语拖音成功");
      wordDraggingSound();
    }

    /**
     * 局部变速
     * 
     * 此函数用于获取选中文本并显示局部变速对话框
     */
    function localSpeedChange() {
      // 获取textarea元素
      const textarea = textareaRef.value;
      if (textarea) {
        // 获取选中文本的起始和结束位置
        let start = textarea.selectionStart || 0;
        let end = textarea.selectionEnd || 0;
        // 提取选中的文本
        let selectedText = textarea.value.substring(start, end);

        // 如果没有选中文本，则显示错误消息并返回
        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }
        // successMessge("局部变速成功");
        showPopover.value = true; // 打开 popover
      }
    }

    /**
     * 顿挫调节
     * 
     * 此函数用于获取选中文本并显示顿挫调节对话框
     */
    function abortiveRegulation() {
      // 获取textarea元素
      const textarea = textareaRef.value;
      if (textarea) {
        // 获取选中文本的起始和结束位置
        let start = textarea.selectionStart || 0;
        let end = textarea.selectionEnd || 0;
        // 提取选中的文本
        let selectedText = textarea.value.substring(start, end);

        // 如果没有选中文本，则显示错误消息并返回
        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }
        //successMessge("顿挫调节成功");
        showAbortiveRegulationPopover.value = true;
      }
    }

    /**
     * 插入停顿
     * 
     * 此函数用于显示插入停顿对话框
     */
    function insertPause() {
      // successMessge("插入停顿成功")
      if (insertPauseRef.value) {
        insertPauseRef.value.dialogVisible = true;
      }
    }

    /**
     * 读音连续
     * 
     * 此函数用于获取选中文本并显示读音连续对话框
     */
    function continuousPronunciation() {
      //successMessge("读音连续成功")
      const textarea = textareaRef.value;
      if (textarea) {
        const start = textarea.selectionStart || 0;
        const end = textarea.selectionEnd || 0;
        const selectedText = textarea.value.substring(start, end);

        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }

        if (selectedText.length > 7) {
          errorMessge('选中文本长度超过7个字符，不合法');
        } else {
          if (selectedText.length > 0) {
            textarea.value =
              textarea.value.substring(0, start) +
              '#cr' +
              selectedText +
              '!cr#' +
              textarea.value.substring(end);
            // 重新设置光标位置
            setTimeout(() => {
              textarea.selectionStart = start + 2;
              textarea.selectionEnd = end + 4;
            }, 0);
          }
        }
      }
    }

    /**
     * 段末加停顿
     * 
     * 此函数用于显示段末加停顿对话框
     */
    function endStop() {
      //successMessge("段末加停顿成功")
      if (duanMoJiaTingDunRef.value) {
        duanMoJiaTingDunRef.value.dialogVisible = true;
      }
    }

    /**
     * 紧凑模式
     * 
     * 此函数用于显示紧凑模式对话框
     */
    function compactMode() {
      //successMessge("紧凑模式成功")
      showCompactModePopover.value = true;
    }

    /**
     *  解说增强
     * 
     * 此函数用于显示解说增强对话框
     */
    function interpretationEnhancement() {
      successMessge("解说增强成功")
      showInterpretationEnhancementPopover.value = true;
    }

    /**
     * 背景音乐
     * 
     * 此函数用于显示背景音乐对话框
     */
    function backgroundMusic() {
      //successMessge("背景音乐成功");
      if (backgroundMusicRef.value) {
        backgroundMusicRef.value.dialogVisible = true;
      }
    }

    /**
     * 变音
     * 
     * 此函数用于显示变音对话框
     */
    function inflection() {
      successMessge("变音成功");
      showInflectionPopover.value = true;
    }

    /**
     * 字幕配置
     * 
     * 此函数用于显示字幕配置对话框
     */
    function captioning() {
      successMessge("字幕配置成功");
      if (subtitleSettingsRef.value) {
        subtitleSettingsRef.value.dialogVisible = true;
      }
    }

    /**
     * 多人对话
     * 
     * 此函数用于显示多人对话对话框
     */
    function multiConversation() {
      successMessge("多人对话成功")
    }


    /**
     * 插入停顿事件处理
     * 
     * 此函数用于在文本中插入停顿
     */
    function handleInsertPause(text: string) {
      //successMessge(text);
      insertText(text);
    }

    /**
     * 段末加停顿事件处理函数
     * 在文本段落的末尾添加特定的停顿符号或文本
     * 
     * @param {string} text - 要添加的停顿文本
     * @param {any} args - 包含操作参数的对象
     */
    function handleDuanMoJiaTingDun(text: string, args: any) {
      // 获取参数中的段落类型和是否空白行的设置
      let paragraph: string = args.paragraph;
      let blankLine: boolean = args.blankLine;
      let itemText: string = "";
      let s: string = "";
      let cumulativeLength = 0;
      let ischanged = false;

      // 将文本域的值按行分割成数组
      let paragraphs: string[] = textarea.value.split('\n');

      //从最后行向第一行处理删除最后行添加的空行
      for (let i = paragraphs.length - 1; i >= 0; i--) {
        if (paragraphs[i]) {
          break;
        }
        else {
          paragraphs.pop();
        }
      }

      // 如果不重置文本
      if (args.reset == false) {

        // 如果对所有段落进行操作
        if (paragraph == "all") {
          // 遍历每一行，根据是否空白行的设置决定是否添加停顿文本
          for (let i = 0; i < paragraphs.length; i++) {
            itemText = paragraphs[i];
            if (blankLine) {
              itemText = itemText + text;
            }
            else {
              if (itemText) {
                itemText = itemText + text;
              }
            }

            s = s + itemText + "\n";

          }
          // 更新文本域的值
          textarea.value = s;
        }
        // 如果只对当前段落进行操作
        else if (paragraph == "current") {
          ischanged = false;

          // 根据是否空白行的设置，找到当前光标位置所在的段落并添加停顿文本
          if (blankLine) {

            for (let i = 0; i < paragraphs.length; i++) {
              itemText = paragraphs[i];
              cumulativeLength += itemText.length + 1; // +1 for the newline character            

              if (cursorPosition.value <= cumulativeLength) {
                paragraphs[i] = paragraphs[i] + text;
                ischanged = true;

                break;
              }
            }
            // 如果进行了修改，重新构建文本域的值
            if (ischanged == true) {
              for (let i = 0; i < paragraphs.length; i++) {
                itemText = paragraphs[i];
                s = s + itemText + "\n";
              }

              textarea.value = s;
            }

          }
          else {
            // 对非空白行进行操作
            for (let i = 0; i < paragraphs.length; i++) {
              itemText = paragraphs[i];
              cumulativeLength += itemText.length + 1; // +1 for the newline character            

              if (itemText) {

                if (cursorPosition.value <= cumulativeLength) {
                  console.log("itemText:", itemText);
                  paragraphs[i] = paragraphs[i] + text;
                  ischanged = true;
                  break;
                }
              }
            }
            // 如果进行了修改，重新构建文本域的值
            if (ischanged == true) {
              for (let i = 0; i < paragraphs.length; i++) {
                itemText = paragraphs[i];
                s = s + itemText + "\n";
              }

              textarea.value = s;
            }

          }

        }
      }
      else {
        // 重置文本
        for (let i = 0; i < paragraphs.length; i++) {
          itemText = paragraphs[i];
          itemText = replaceSpecialStrings(itemText);

          s = s + itemText + "\n";
        }

        textarea.value = s;
      }
    }


    /**
     * 给textarea中的光标所在位置插入文本值
     * 
     * 此函数用于在textarea中插入文本
     */
    function insertText(text: string) {
      if (cursorPosition.value >= 0 && textareaRef.value) {
        const currentValue = textareaRef.value.value;
        const beforeCursor = currentValue.substring(0, cursorPosition.value);
        const afterCursor = currentValue.substring(cursorPosition.value);
        const newValue = beforeCursor + text + afterCursor;

        // 更新 textarea 的值
        textareaRef.value.value = newValue;

        // 移动光标到插入文本后的位置
        cursorPosition.value += text.length;
        textareaRef.value.setSelectionRange(cursorPosition.value, cursorPosition.value);
      }
    }

    /**
     * 段落添加停顿时间的还原重軒功能中替换特殊字符串
     * 
     * 此函数用于在段落添加停顿时间的还原重軒功能中替换特殊字符串
     */
    function replaceSpecialStrings(text: string): string {
      let s: string = text;
      s = s.replace(/#!.*?#/g, '');

      return s;
    };

    // 局部变速选择处理
    /**
     * 处理本地速度变化点击事件
     * @param {number} rate - 速度比率，用于插入到选中文本的速度效果中
     */
    ///局部变速
    const handleLocalSpeedChangeClick = (rate: number) => {
      // 获取textarea元素
      const textarea = textareaRef.value;
      if (textarea) {
        // 获取选中文本的起始和结束位置
        let start = textarea.selectionStart || 0;
        let end = textarea.selectionEnd || 0;
        // 提取选中的文本
        let selectedText = textarea.value.substring(start, end);

        // 如果没有选中文本，则显示错误消息并返回
        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }

        const oldStart = textarea.value.indexOf("#%");
        const oldEnd = textarea.value.indexOf("%#");

        // 如果选中的文本长度大于0，则插入速度效果标记
        if (selectedText.length > 0) {
          textarea.value =
            textarea.value.substring(0, start) +
            '#%' + rate.toString() + '|' +
            selectedText +
            '%#' +
            textarea.value.substring(end);
          // 重新设置光标位置
          setTimeout(() => {
            textarea.selectionStart = start + 2;
            textarea.selectionEnd = end + 4;
          }, 0);
        }
      }
      // 关闭 popover
      showPopover.value = false;
    };

    // 词语拖音
    /**
     * 处理词语拖音
     */
    const wordDraggingSound = () => {
      // 获取textarea元素
      const textarea = textareaRef.value;
      if (textarea) {
        // 获取选中文本的起始和结束位置
        let start = textarea.selectionStart || 0;
        let end = textarea.selectionEnd || 0;
        // 提取选中的文本
        let selectedText = textarea.value.substring(start, end);

        // 如果没有选中文本，则显示错误消息并返回
        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }

        // 检查选中文本中是否已包含速度效果标记，如果是，则显示错误消息并返回
        if (selectedText.indexOf("#drag|") >= 0 || selectedText.indexOf("!drag#") >= 0) {
          errorMessge("插入失败,不能重复添加效果");
          return;
        }

        // 检查选中文本前后是否已存在速度效果标记，以避免重复插入效果
        // 取选中文本的起始位置前面文本中的最后一个开始标记位置
        let oldStart = textarea.value.substring(0, start).lastIndexOf("#drag|");
        // 取选中文本的结束位置后面文本中的第一个结束标记位置
        let oldEnd = textarea.value.substring(end).indexOf("!drag#");

        // 取选中文本的起始位置前面文本中的最后一个结束标记位置
        let oldEnd2 = textarea.value.substring(0, start).lastIndexOf("!drag#");

        // 取选中文本的结束位置后面文本中的第一个开始标记位置
        let oldStart2 = textarea.value.substring(end).indexOf("#drag|");

        // 没有最近的结束标记和开始标记
        if ((oldStart <= start && oldStart >= 0 && oldEnd2 < 0) && (end <= end + oldEnd && oldEnd >= 0 && oldStart2 < 0)) {
          errorMessge("插入失败,不能重复添加效果");
          return;
        }

        // 如果检测到重复的效果标记，则显示错误消息并返回
        if ((oldStart <= start && oldStart >= 0 && oldStart > oldEnd2) && (end <= end + oldEnd && oldEnd >= 0 && oldEnd < oldStart2)) {
          errorMessge("插入失败,不能重复添加效果");
          return;
        }

        // 如果选中的文本长度大于0，则插入速度效果标记
        if (selectedText.length > 0) {
          textarea.value =
            textarea.value.substring(0, start) +
            '#drag|' +
            selectedText +
            '!drag#' +
            textarea.value.substring(end);
          // 重新设置光标位置
          setTimeout(() => {
            textarea.selectionStart = start + 2;
            textarea.selectionEnd = end + 4;
          }, 0);
        }
      }
    };

    // 顿挫调节
    /**
     * 处理顿挫调节
     */
    const handleAbortiveRegulationClick = (rate: string) => {
      // 获取textarea元素
      const textarea = textareaRef.value;
      if (textarea) {
        // 获取选中文本的起始和结束位置
        let start = textarea.selectionStart || 0;
        let end = textarea.selectionEnd || 0;
        // 提取选中的文本
        let selectedText = textarea.value.substring(start, end);

        // 如果没有选中文本，则显示错误消息并返回
        if (selectedText.length <= 0) {
          errorMessge('请选中文本');
          return;
        }

        if (rate !== "") {
          // 检查选中文本中是否已包含速度效果标记，如果是，则显示错误消息并返回
          if (selectedText.indexOf("#tone|") >= 0 || selectedText.indexOf("!tone#") >= 0) {
            errorMessge("插入失败,不能重复添加效果");
            return;
          }
        }

        // 检查选中文本前后是否已存在速度效果标记，以避免重复插入效果
        // 取选中文本的起始位置前面文本中的最后一个开始标记位置
        let oldStart = textarea.value.substring(0, start).lastIndexOf("#tone|");
        // 取选中文本的结束位置后面文本中的第一个结束标记位置
        let oldEnd = textarea.value.substring(end).indexOf("!tone#");

        // 取选中文本的起始位置前面文本中的最后一个结束标记位置
        let oldEnd2 = textarea.value.substring(0, start).lastIndexOf("!tone#");

        // 取选中文本的结束位置后面文本中的第一个开始标记位置
        let oldStart2 = textarea.value.substring(end).indexOf("#tone|");


        if (rate !== "") {
          // 没有最近的结束标记和开始标记
          if ((oldStart <= start && oldStart >= 0 && oldEnd2 < 0) && (end <= end + oldEnd && oldEnd >= 0 && oldStart2 < 0)) {
            errorMessge("插入失败,不能重复添加效果");
            return;
          }
          // 如果检测到重复的效果标记，则显示错误消息并返回
          if ((oldStart <= start && oldStart >= 0 && oldStart > oldEnd2) && (end <= end + oldEnd && oldEnd >= 0 && oldEnd < oldStart2)) {
            errorMessge("插入失败,不能重复添加效果");
            return;
          }


        }


        // 如果选中的文本长度大于0，则插入速度效果标记
        if (selectedText.length > 0) {
          if (rate == "") {
            // 定义正则表达式
            const regex = /#tone\|[^|]*\|/g;
            const regex2 = /!tone#/g;
            // 替换匹配到的内容为空字符串
            textarea.value =
              textarea.value.substring(0, start) +
              selectedText.replace(regex, '').replace(regex2, '') +
              textarea.value.substring(end);
          }
          else {
            textarea.value =
              textarea.value.substring(0, start) +
              '#tone|' + rate + '|' +
              selectedText +
              '!tone#' +
              textarea.value.substring(end);
          }

        }
      }
      // 关闭 popover
      showAbortiveRegulationPopover.value = false;
    }


    /**
     * 处理声音变调点击事件
     * @param key 声音变调的键值
     * @param title 声音变调的标题
     */
    function handleInflectionClick(key: string, title: string) {
      // 发射声音变调事件
      showInflectionPopover.value = false;
      inflectionTitle.value = title;
    }

    /**
 * 切换紧凑模式的内容
 * 此函数用于更新紧凑模式的状态
 * @param {boolean} value - 表示当前紧凑模式的状态，true表示开启，false表示关闭
 */
    const toggleCompactModeContent = (value) => {
      isCompactMode.value = value;
    };

    /**
     * 取消紧凑模式的显示
     * 这个函数用于在用户界面中隐藏紧凑模式的弹出框
     * 当用户触发取消事件时，这个函数会被调用，从而隐藏弹出框
     */
    const handleCompactModeCancel = () => {
      // 取消操作
      showCompactModePopover.value = false;
    };

    /**
     * 处理紧凑模式确认操作
     * 此函数在用户确认进入紧凑模式时被调用由于当前版本中该功能尚未开发完成，
     * 因此该函数仅显示一个提示消息，并关闭紧凑模式弹出框
     */
    const handleCompactModeConfirm = () => {
      // 显示提示消息，表明紧凑模式设置操作尚未开发完成
      successMessge("这里开始设置操作,未开发完成");

      // 关闭紧凑模式弹出框
      showCompactModePopover.value = false;
    };

    /**
     * 启用或禁用解释增强功能
     * 此函数用于根据传入的值切换解释增强功能的启用状态
     * 
     * @param {boolean} value - 表示是否启用解释增强功能的布尔值
     */
    const InterpretationEnhancementToggleContent = (value) => {
      // 将全局变量设置为传入的值，以启用或禁用解释增强功能
      isInterpretationEnhancementEnabled.value = value;
      // 显示操作成功的消息，此处为模拟操作，实际功能未开发完成
      successMessge("这里开始设置操作,未开发完成");
    };


    /**
     * 当文本域内容发生变化时触发的事件处理函数
     * 该函数的主要作用是检查用户输入的配音文本，并在不为空时将其保存到服务器中
     * 
     * @param {Event} event - 触发的事件对象，用于获取文本域的当前值
     */
    const onTextareaChange = (event) => {
      // 初始化语音数据变量，用于存储当前选中的配音项数据
      let voiceData: VoiceActor = undefined;

      // 配音文本不为空则保存到服务器中
      if (!(textarea.value == "" || textarea.value == null || textarea.value == undefined)) {
        // 检查发音参考对象及其当前项是否存在，若存在则将其赋值给语音数据变量
        if (pronunciationRef.value != null && pronunciationRef.value.currentItem != null && pronunciationRef.value.currentItem != undefined) {
          voiceData = pronunciationRef.value.currentItem;
          // 调用保存临时数据的函数，将当前的语音数据和文本域的值保存到服务器中
          saveTempData(voiceData, textarea.value);
        }
      }
    }

    /**
     * 保存临时配音数据到服务器
     * 
     * 此函数负责将用户选择的配音参数和文本内容上传到服务器它首先构造了一个包含所有必要信息的FormData对象，
     * 然后使用axios库发送POST请求到服务器的相应API端点成功上传后，返回服务器的响应对象；
     * 如果上传过程中遇到错误，则捕获该错误并将其打印到控制台，同时抛出错误以便于调用者处理
     * 
     * @param voiceData 当前选择的配音演员信息，包括发音人简称、中文名、角色ID、情绪ID等
     * @param text 用户输入的需要配音的文本内容
     * @returns Promise 返回一个Promise对象，解析为服务器的响应数据
     */
    const saveTempData = async (voiceData: VoiceActor, text: string) => {
      // 获取基础URL
      const baseUrl: string = GetBaseURL();
      //取用户名称
      const userName = getCookie('TR_username');
      // 创建FormData对象用于构造表单数据
      const formData = new FormData();
      //配音参数保存类
      const audioRecord = new AudioRecord();
      //Taken值
      let taken:string="";

      //设置值
      audioRecord.id = 0; // 唯一标识符
      audioRecord.userName = userName; // 用户名
      audioRecord.title="未命名文件";  //标题
      audioRecord.text = text; // 文本内容
      audioRecord.voiceShortName = voiceData.ShortName;  // 发音人简称(英文名称)
      audioRecord.voiceDisplayName = voiceData.DisplayName; // 发音人(中文名称)
      audioRecord.api_role_id = voiceData.api_role_id; //选中的角色id
      audioRecord.api_style_id = voiceData.api_style_id;  //选中的情绪id
      audioRecord.rate = voiceData.paceValue.toString(); //语速
      audioRecord.volume = voiceData.volume; //音量
      audioRecord.pitch = (voiceData.pitchValue * 100).toString() + "%";  //音调
      audioRecord.styleDegree = voiceData.styleDegree.toString();  //讲话风格的强度，可以指定更强或更柔和的风格，使语音更具表现力或更柔和， 可接受值的范围为：0.01 到 2（含），默认值为 1，表示预定义的风格强度，最小单位为 0.01，表示略倾向于目标风格，值为 2 表示是默认风格强度的两倍。
      audioRecord.breakTime = '250';  //停顿时间
      audioRecord.createtime = new Date().toISOString();  //创建时间
      audioRecord.updatetime = new Date().toISOString();  //更新时间
      audioRecord.audioUrl = audioUrlall.value;    //音频地址
      audioRecord.captionUrl = "";  //字幕地址，先为空等待开发
      audioRecord.memberId = 0;    //会员id，先为空等待开发

      // 向formData中添加订单信息
      formData.append('id', audioRecord.id);
      formData.append('userName', audioRecord.userName);
      formData.append('title', audioRecord.title);      
      formData.append('text', audioRecord.text);
      formData.append('ShortName', audioRecord.voiceShortName);
      formData.append('DisplayName', audioRecord.voiceDisplayName);
      formData.append('api_role_id', audioRecord.api_role_id);
      formData.append('api_style_id', audioRecord.api_style_id);
      formData.append('rate', audioRecord.rate);
      formData.append('volume', audioRecord.volume);
      formData.append('pitch', audioRecord.pitch);
      formData.append('styleDegree', audioRecord.styleDegree);
      formData.append('breakTime', audioRecord.breakTime);
      formData.append('createtime', audioRecord.createtime);
      formData.append('updatetime', audioRecord.updatetime);
      formData.append('audioUrl', audioRecord.audioUrl);
      formData.append('captionUrl', audioRecord.captionUrl);
      formData.append('memberId', audioRecord.memberId);

      console.log('保存配音数据',audioRecord);

      try {
        // 获取并设置token
        taken = getCookie("TR_token");
        // 使用axios发送POST请求提交数据到服务器
        const response = await axios.post(
          `${baseUrl}/addons/vip/api`,
          formData,
          {
            headers: {
              'token': taken
            }
          }
        );
        // 返回响应对象
        return response;
      } catch (error) {
        // 捕获错误并打印到控制台
        console.error('Error错误捕捉:', error);
        // 抛出错误以便于调用者处理
        //throw error;
      }
    }

    //根据配音记录ID加载配音记录，如：配音的文本，角色，情绪等
    const loadDuggingRecord = () => {
      if(props.audioId != undefined){
        //从服务器上加载配音记录数据，这里写取数据的逻辑

        //实现在配音角色列表里面选中该角色，这里2是测试数据，实际是从配音记录中获取的
        //voiceActorId.value=2;
   
        successMessge("从服务器上加载配音记录数据,未开发完成");
        console.log("从服务器上加载配音记录数据,未开发完成",props.audioId);
      }
    }

    /**
     * 初始化时设置默认主题
     * 此函数用于在页面加载时设置默认主题
     */
    onMounted(() => {
      const user = getCookie('nightMode');
      if (user == "") {
        isDarkMode.value = false;
      } else if (user == "dark") {
        isDarkMode.value = true;
      } else {
        isDarkMode.value = false;
      };

      toggleTheme(isDarkMode.value);

      if (user == "") {
        targetDiv.value.className = "light";
      } else {

        targetDiv.value.className = user;
      }

      //加载配音记录,从会员中心的配音记录跳转过来，根据配音记录Id 加载配音记录
      loadDuggingRecord()


      audioPlayer.value = listeningAudioPlayer.value;

          if (audioPlayer.value) {
            // 显示音频播放器
            audioPlayer.value.className = 'middle-4';
          }

    });

    return {
      //主题
      isDarkMode,
      //耳机
      Headset,
      //文档
      Document,
      //下载
      Download,
      //视频
      VideoCameraFilled,
      //月亮
      Moon,
      //太阳
      Sunny,
      //切换主题
      toggleTheme,
      //目标div
      targetDiv,
      //文本框
      textarea,
      //视频播放
      VideoPlay,
      //刷新父级
      refreshParent,
      //检查
      Check,
      //段落添加
      segmentAddition,
      //格式化
      formatting,
      //纯文本
      plaintext,
      //清除
      clear,
      //删除
      Delete,
      //编辑
      Edit,
      //消息
      Message,
      //搜索
      Search,
      //星星
      Star,
      //操作
      Operation,
      //行李箱
      Suitcase,
      //铅笔
      EditPen,
      //解释增强
      Inationenhancement,
      //试听
      audition,
      //整句
      wholeSentence,
      //点击
      handleClick,
      //生成配音
      Generatedubbing,
      //下载配音
      Downloaddubbing,
      //下载视频
      Downloadvideo,
      //生成字幕
      Generatesubtitles,
      //下载字幕
      Downloadsubtitles,
      //发音
      pronunciationRef,
      //文本转语音
      callTextToAudioPlay,
      //音频播放
      audioPlayer,
      //音频
      audioUrl,
      //文本框引用
      textareaRef,
      //句子文本
      sentenceText,
      //重置音频
      resetAudio,
      //选择配音演员
      handleVoiceActorSelected,
      //听音频播放
      listeningAudioPlayer,
      //试听音频播放
      stAudioPlayer,
      //字幕音频播放
      zjAudioPlayer,
      //获取句子
      getSentenceAtCursor,

      importCopy,
      //同义词
      synonym,
      //全同义词
      fullSynonym,
      //敏感词
      sensitiveWords,
      //多音字
      multitone,
      //批量纠错
      batchCorrection,
      //数字发音
      numberPronunciation,
      //卷舌音
      rhoticAccent,
      //单词拖拽
      wordDrag,
      //局部速度变化
      localSpeedChange,
      //顿挫调节
      abortiveRegulation,
      //插入暂停
      insertPause,
      //连续发音
      continuousPronunciation,
      //结束停顿
      endStop,
      //紧凑模式
      compactMode,
      //解释增强
      interpretationEnhancement,
      //背景音乐
      backgroundMusic,
      //声音变调
      inflection,
      //字幕
      captioning,
      //多轮对话
      multiConversation,
      //对话敏感词
      dialogsensitiveWords,
      //对话同义词
      dialogfullSynonym,
      //对话批量纠错
      dialogbatchCorrection,
      //关闭
      handleClose,
      //全同义词页面文本内容
      fullSynonymPageTextContent,
      //全同义词更新
      fullSynonymUpdated,
      //敏感词更新
      sensitiveWordsUpdated,
      //批量纠错更新
      batchCorrectionUpdated,
      //鼠标抬起
      handleMouseUp,
      //选中文本
      selectedText,
      //多音字
      multitoneRef,
      //多音字对话框
      multitoneDialogVisible,
      //数字发音对话框
      numberPronunciationDialogVisible,
      //多音字选项
      multitoneOptions,
      //数字发音选项
      numberPronunciationOptions,
      //多音字选择
      handleMultitoneSelect,
      //数字发音选择
      handleNumberPronunciationSelect,
      //数字发音引用
      numberPronunciationRef,
      //音频状态
      audioState,
      //提取文件名
      extractFileName,
      //文本改变
      onTextChange,
      //验证
      validate,
      //插入暂停
      InsertPause,
      //插入暂停引用
      insertPauseRef,
      //插入暂停
      handleInsertPause,
      //光标位置
      cursorPosition,
      //插入文本
      insertText,
      //段落加停顿引用
      duanMoJiaTingDunRef,
      //段落加停顿
      handleDuanMoJiaTingDun,
      //当前段落
      currentParagraph,
      //替换特殊字符串
      replaceSpecialStrings,
      //局部速度变化点击
      handleLocalSpeedChangeClick,
      //速度变化率
      speedChangeRates,
      //弹出框
      showPopover,
      //局部速度变化引用
      localSpeedChangeRef,
      //顿挫调节引用
      abortiveRegulationRef,
      //顿挫调节弹出框
      showAbortiveRegulationPopover,
      //顿挫调节点击
      handleAbortiveRegulationClick,
      /* 定义示例 */
      synonymRef,
      //同义词弹出框
      compactModeRef,
      //解释增强引用
      interpretationEnhancementRef,
      //同义词弹出框
      synonymDialogVisible,
      //紧凑模式
      isCompactMode,
      //紧凑模式
      compactModeDuration,
      //紧凑模式时长
      showInterpretationEnhancementPopover,
      //解释增强
      isInterpretationEnhancementEnabled,
      //解释增强
      synonymOptions,
      //同义词
      handleSynonymSelect,
      //紧凑模式
      showCompactModePopover,
      //紧凑模式
      backgroundMusicRef,
      //背景音乐
      BackgroundMusic,
      //背景音乐内容
      BackgroundMusicContent,
      //声音变调
      inflectionRef,
      //声音变调
      showInflectionPopover,
      //声音变调点击
      handleInflectionClick,
      //声音变调标题
      inflectionTitle,
      //紧凑模式
      toggleCompactModeContent,
      //紧凑模式取消
      handleCompactModeCancel,
      //紧凑模式
      handleCompactModeConfirm,
      //解释增强
      InterpretationEnhancementToggleContent,
      //声音变调
      Inflection,
      //音频时长
      duration,
      //音频播放
      audioUrlipdz,
      //格式化时间
      formattedDuration,
      //错误信息
      error,
      //获取合并后的音频
      audioUrlall,
      //字幕设置
      SubtitleSettings,
      //字幕设置
      subtitleSettingsRef,
      //段落列表
      segmentsList,
      //全屏加载
      fullscreenLoading,
      //保存配音参数和文本到服务器
      saveTempData,
      //监控配音文本改变事件处理方法
      onTextareaChange,
      //根据配音记录id 加载配音记录
      loadDuggingRecord,
      //配音角色id
      voiceActorId,
      //listeningAudioPlayer显示或隐藏
      listeningAudioPlayerShow 
    };
  }
};
</script>

<style scoped>
/* styles.css */

.hidden-audio {
  display: none;
  /* 隐藏音频元素 */
}

.custom-textarea-container {
  position: relative;
  width: 100%;
  max-width: 100%;

  margin: 0 auto;
}

.custom-textarea {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;

  border-radius: 4px;
  resize: none;
  font-size: 14px;
  line-height: 1.5;
  min-height: 400px;
  /* 19行 * 10px行高 */
  max-height: 400px;
  /* 19行 * 10px行高 */
  overflow-y: auto;
}

.word-limit {
  margin-left: 60%;
  bottom: 5px;
  right: 10px;
  width: 50%;
  height: 50px;
  font-size: 12px;
}

.container {
  display: flex;
  flex-wrap: wrap;
  /* 允许项目在必要时换行 */
  gap: 10px;
  /* 项目之间的间距 */
  padding: 10px;
}


.custom-textarea .el-textarea__inner {
  background-color: #f0f0f0 !important;
  /* 设置背景颜色 */
}

.clickable-col img {
  display: block;
  /* 使图片独占一行 */
  margin: 0 auto;
  /* 图片居中 */
}

.responsive-font {
  font-size: calc(0.35vw + 0.5rem);
}

@media screen and (max-width: 1200px) {
  .responsive-font {
    font-size: calc(0.3vw + 0.5rem);
  }
}

@media screen and (max-width: 768px) {
  .responsive-font {
    font-size: calc(0.2vw + 0.5rem);
  }
}



/* 调整按钮大小 */
.responsive-button {
  padding: calc(0.3vw + 0.2rem) calc(0.5vw + 0.3rem);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.button-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.button-group {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
}

.popover-content {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  /* 调整按钮之间的间距 */
}

.compactmode-popover-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.compactmode-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  margin-bottom: 16px;
}

.compactmode-title {
  font-weight: bold;
}

.compactmode-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-bottom: 8px;
}

.InterpretationEnhancement-popover-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.InterpretationEnhancement-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  margin-bottom: 16px;
}

.InterpretationEnhancement-title {
  font-weight: bold;
}

.InterpretationEnhancement-content {
  width: 100%;
}

.InterpretationEnhancement-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-bottom: 16px;
}

.InterpretationEnhancement-text {
  width: 100%;
  text-align: center;
  margin-bottom: 8px;
}

.middle-4{
  display: flex; 
  justify-content: center; 
  align-items: center; 
  width: 100%;
  margin-top: 5px; 
}
</style>
